#include "qt_bdm_remuaux_cartier.h"

qt_bdm_remuaux_cartier::qt_bdm_remuaux_cartier(QWidget *parent) :
	QMainWindow(parent)
{
	ui.setupUi(this);

	connect(ui.actionOuvrir_couleur, SIGNAL(triggered()), this, SLOT(ouvrirImageCouleur()));
	connect(ui.actionOuvrir_gris, SIGNAL(triggered()), this, SLOT(ouvrirImageGris()));
	connect(ui.actionOuvrir_session, SIGNAL(triggered()), this, SLOT(ouvrirSession()));
	connect(ui.actionSauvegarder_session, SIGNAL(triggered()), this, SLOT(sauvegarderSession()));
	connect(ui.tabImages, SIGNAL(tabCloseRequested(int)), this, SLOT(fermerTabImage(int)));
	connect(ui.actionHistogrames, SIGNAL(triggered()), this, SLOT(affichageHistogrames()));
	connect(ui.actionDist_Euclid_point, SIGNAL(triggered()), this, SLOT(calculDEPoint()));
	connect(ui.actionDist_Euclid_intervale, SIGNAL(triggered()), this, SLOT(calculDEIntervale()));
	connect(ui.actionCalcul_D_E_lot, SIGNAL(triggered()), this, SLOT(calculDELot()));
	connect(ui.actionCat_gories, SIGNAL(triggered()), this, SLOT(categories()));
	connect(ui.actionModifier_infos, SIGNAL(triggered()), this, SLOT(modifierInfos()));
	connect(ui.actionDist_Levenstein, SIGNAL(triggered()), this, SLOT(distLevenstein()));
	connect(ui.actionRecherche_mot_clef, SIGNAL(triggered()), this, SLOT(rechercheMotClef()));
	connect(ui.actionCreation_Index, SIGNAL(triggered()), this, SLOT(creationIndexChoixLot()));
	connect(ui.actionRech_index_histo, SIGNAL(triggered()), this, SLOT(rechercheHistoIndex()));
	connect(ui.actionRech_Index_Mot_Clef, SIGNAL(triggered()), this, SLOT(rechercheMotIndex()));
	connect(ui.actionVers_LSB_4_4, SIGNAL(triggered()), this, SLOT(choixImageVersLsd44()));
	connect(ui.actionDe_LSB_4_4, SIGNAL(triggered()), this, SLOT(deLsd44()));
	connect(ui.actionVers_LSB, SIGNAL(triggered()), this, SLOT(choixImageVersLsd()));
	connect(ui.actionDe_LSB, SIGNAL(triggered()), this, SLOT(deLsd()));
	connect(ui.actionAfficher, SIGNAL(triggered()), this, SLOT(affAide()));

	listeImages = *new QList<Image> ();
}

qt_bdm_remuaux_cartier::~qt_bdm_remuaux_cartier()
{

}

void qt_bdm_remuaux_cartier::affAide()
{
	DialogAide* dial = new DialogAide(this);
	dial->exec();
}

void qt_bdm_remuaux_cartier::ouvrirImageCouleur()
{
	ouvrirImage(false);
}

void qt_bdm_remuaux_cartier::ouvrirImageGris()
{
	ouvrirImage(true);
}

void qt_bdm_remuaux_cartier::ouvrirImage(bool enGris)
{
	QString fileName = QFileDialog::getOpenFileName(this, tr("Ouvrir Image"),
			QDir::currentPath() + "/image");
	if (!fileName.isEmpty())
	{
		QImage qimage(fileName);
		if (qimage.isNull())
		{
			QMessageBox::information(this, tr("BDM"), tr("Impossible d'ouvrir %1.").arg(fileName));
			return;
		}

		QFileInfo fi(fileName);

		Image* image = new Image();
		image->qImage = qimage;
		if (enGris)
		{
			image->convertirEnNiveauDeGris();
		}
		if (image->estGris)
		{
			image->nom = (fi.fileName()).toStdString() + "(gris)";
		}
		else
		{
			image->nom = (fi.fileName()).toStdString();
		}
		image->calculHistogram();
		image->chemin = fileName.toStdString();

		bool ok;
		QString text = QInputDialog::getText(this, tr("Mot clef"), tr("Mot clef:"),
				QLineEdit::Normal, tr(""), &ok);
		if (ok && !text.isEmpty())
		{
			image->motClef = text.toStdString();
		}

		ajoutImageATab(image);
	}
}

void qt_bdm_remuaux_cartier::ajoutImageATab(Image *image)
{
	listeImages.append(*image);

	QWidget * tab = new ImageTab(this, &(image->qImage));
	ui.tabImages->addTab(tab, QString((image->nom).c_str()));
	ui.tabImages->setCurrentIndex(listeImages.size() - 1);

	ui.actionDist_Euclid_intervale->setEnabled(true);
	ui.actionDist_Euclid_point->setEnabled(true);
	ui.actionHistogrames->setEnabled(true);
	ui.actionCalcul_D_E_lot->setEnabled(true);
	ui.actionCat_gories->setEnabled(true);
	ui.actionDist_Levenstein->setEnabled(true);
	ui.actionModifier_infos->setEnabled(true);
	ui.actionRecherche_mot_clef->setEnabled(true);
	ui.actionSauvegarder_session->setEnabled(true);
	ui.actionCreation_Index->setEnabled(true);
	ui.actionVers_LSB_4_4->setEnabled(true);
	ui.actionDe_LSB_4_4->setEnabled(true);
	ui.actionVers_LSB->setEnabled(true);
	ui.actionDe_LSB->setEnabled(true);
}

void qt_bdm_remuaux_cartier::ouvrirSession()
{
	QString fileName = QFileDialog::getOpenFileName(this, tr("Ouvrir session"),
			QDir::currentPath() + "/sessions");
	QList<Image> listeImages2;
	if (!fileName.isEmpty())
	{
		QFileInfo fi(fileName);
		listeImages2 = deserializeImages(fi.absoluteFilePath().toStdString());
	}
	for (int i = 0; i < listeImages2.size(); i++)
	{

		QString qFilename(listeImages2[i].chemin.c_str());
		QImage qimage(qFilename);
		if (qimage.isNull())
		{
			QMessageBox::information(this, tr("BDM"), tr("Impossible d'ouvrir %1.").arg(qFilename));
			return;
		}
		listeImages2[i].qImage = qimage;
		ajoutImageATab(&(listeImages2[i]));
	}
}

void qt_bdm_remuaux_cartier::sauvegarderSession()
{
	QString fileName = QFileDialog::getSaveFileName(this, tr("Ouvrir session"),
			QDir::currentPath() + "/sessions");
	if (!fileName.isEmpty())
	{
		serializeImages(listeImages, fileName.toStdString());
	}
}

QImage qt_bdm_remuaux_cartier::transformeGris(QImage image)
{
	int i, j, gray;
	QRgb couleur;

	for (j = 0; j < image.height(); j++)
	{
		for (i = 0; i < image.width(); i++)
		{
			couleur = image.pixel(i, j);
			gray = qGray(couleur);
			couleur = qRgb(gray, gray, gray);
			image.setPixel(i, j, couleur);
		}
	}

	return image;
}

void qt_bdm_remuaux_cartier::calculHistogram(Image * image)
{
	int i, j;
	QColor couleur;

	for (i = 0; i < 256; i++)
	{
		image->histogram[Image::rouge][i] = 0;
		image->histogram[Image::vert][i] = 0;
		image->histogram[Image::bleu][i] = 0;
		image->histogram[Image::gris][i] = 0;
	}

	for (j = 0; j < image->qImage.height(); j++)
	{
		for (i = 0; i < image->qImage.width(); i++)
		{
			if (image->estGris)
			{
				couleur = image->qImage.pixel(i, j);
				image->histogram[Image::gris][couleur.red()]++;
			}
			else
			{
				couleur = image->qImage.pixel(i, j);
				image->histogram[Image::rouge][couleur.red()]++;
				image->histogram[Image::vert][couleur.green()]++;
				image->histogram[Image::bleu][couleur.blue()]++;
			}
		}
	}
}

void qt_bdm_remuaux_cartier::fermerTabImage(int index)
{
	ui.tabImages->removeTab(index);

	listeImages.removeAt(index);

	if (listeImages.count() <= 0)
	{
		ui.actionDist_Euclid_intervale->setEnabled(false);
		ui.actionDist_Euclid_point->setEnabled(false);
		ui.actionHistogrames->setEnabled(false);
		ui.actionCalcul_D_E_lot->setEnabled(false);
		ui.actionCat_gories->setEnabled(false);
		ui.actionDist_Levenstein->setEnabled(false);
		ui.actionModifier_infos->setEnabled(false);
		ui.actionRecherche_mot_clef->setEnabled(false);
		ui.actionSauvegarder_session->setEnabled(false);
		ui.actionCreation_Index->setEnabled(false);
		ui.actionVers_LSB_4_4->setEnabled(false);
		ui.actionDe_LSB_4_4->setEnabled(false);
		ui.actionVers_LSB->setEnabled(false);
		ui.actionDe_LSB->setEnabled(false);
	}

}

void qt_bdm_remuaux_cartier::affichageHistogrames()
{
	DialogHistogram dial(this, &listeImages[ui.tabImages->currentIndex()]);
	dial.exec();
}

void qt_bdm_remuaux_cartier::calculDEPoint()
{
	DialogDistEuclPoint
			dPoint(this, listeImages, listeImages[ui.tabImages->currentIndex()].estGris);
	connect(&dPoint, SIGNAL(retourDialog(int,int)), this, SLOT(traitementDEPoint(int,int)));
	dPoint.exec();
}

void qt_bdm_remuaux_cartier::calculDEIntervale()
{
	DialogDistEuclIntervale dIntervale(this, listeImages,
			listeImages[ui.tabImages->currentIndex()].estGris);
	connect(&dIntervale, SIGNAL(retourDialog(int,int,int)), this,
			SLOT(traitementDEIntervale(int,int,int)));
	dIntervale.exec();
}

void qt_bdm_remuaux_cartier::traitementDEPoint(int valeur, int index)
{
	QString message;
	float ** histo2 = listeImages[ui.tabImages->currentIndex()].histogram;

	if (listeImages[index].estGris)
	{
		float distg;
		distg = listeImages[index].distanceEuclidienne(histo2, Image::gris, valeur, valeur);
		message = QString("\tPour le gris : %1").arg(distg);
	}
	else
	{
		float distr, distv, distb;
		distr = listeImages[index].distanceEuclidienne(histo2, Image::rouge, valeur, valeur);
		distv = listeImages[index].distanceEuclidienne(histo2, Image::vert, valeur, valeur);
		distb = listeImages[index].distanceEuclidienne(histo2, Image::bleu, valeur, valeur);
		message = QString("\tPour le rouge : %1\n\tPour le vert : %2\n\tPour le bleu : %3").arg(
				distr).arg(distv).arg(distb);
	}
	QMessageBox::information(this, tr("Distance Euclidienne"), message);
}

void qt_bdm_remuaux_cartier::traitementDEIntervale(int min, int max, int index)
{
	QString message;
	float ** histo2 = listeImages[ui.tabImages->currentIndex()].histogram;

	if (listeImages[index].estGris)
	{
		float distg;
		distg = listeImages[index].distanceEuclidienne(histo2, Image::gris, min, max);
		message = QString("Pour le gris : %1").arg(distg);
	}
	else
	{
		float distr, distv, distb;
		distr = listeImages[index].distanceEuclidienne(histo2, Image::rouge, min, max);
		distv = listeImages[index].distanceEuclidienne(histo2, Image::vert, min, max);
		distb = listeImages[index].distanceEuclidienne(histo2, Image::bleu, min, max);
		message
				= QString("Pour le rouge : %1\nPour le vert : %2\nPour le bleu : %3").arg(distr).arg(
						distv).arg(distb);
	}
	QMessageBox::information(this, tr("Distance Euclidienne"), message);
}

void qt_bdm_remuaux_cartier::calculDELot()
{
	DialogChoixLot dial(this, listeImages, DialogChoixLot::calculDELot);
	connect(&dial, SIGNAL(retourDialogCalcDELot(bool *)), this, SLOT(traitementDELot(bool *)));
	dial.exec();
}

void qt_bdm_remuaux_cartier::traitementDELot(bool * checkedIndex)
{
	QList<Image> imagesSelectionnes = *new QList<Image> ();
	QList<comparaisondeDeuxImages> comparaisonsImagesSelectionnes = *new QList<
			comparaisondeDeuxImages> ();

	int i, j;
	for (i = 0; i < listeImages.size(); i++)
	{
		if (checkedIndex[i])
		{
			imagesSelectionnes.append(listeImages[i]);
		}
	}

	for (i = 0; i < imagesSelectionnes.size(); i++)
	{
		for (j = 0; j < i; j++)
		{
			comparaisonsImagesSelectionnes.append(
					*new comparaisondeDeuxImages(&imagesSelectionnes[i], &imagesSelectionnes[j]));
		}
	}

	//affichage
	QStringList nomImages = QStringList();
	for (i = 0; i < imagesSelectionnes.size(); i++)
	{
		nomImages.append((QString) (imagesSelectionnes[i].getNom().c_str()));
	}

	DialogAffichageDELot w(this, nomImages);
	int k = 0;

	for (i = 0; i < imagesSelectionnes.size(); i++)
	{
		for (j = 0; j < i; j++)
		{
			w.AddRow(i, j, comparaisonsImagesSelectionnes.at(k).distanceEuclidienneSombre,
					comparaisonsImagesSelectionnes.at(k).distanceEuclidienneMedianes,
					comparaisonsImagesSelectionnes.at(k).distanceEuclidienneSombre);
			k++;
		}
	}

	w.exec();
}

void qt_bdm_remuaux_cartier::categories()
{
	DialogChoixLot dial(this, listeImages, DialogChoixLot::categories);
	connect(&dial, SIGNAL(retourDialogCalcCategories(bool *)), this,
			SLOT(traitementCategories(bool *)));
	dial.exec();
}

void qt_bdm_remuaux_cartier::traitementCategories(bool * checkedIndex)
{
	QList<Image> imagesSelectionnes = *new QList<Image> ();

	int i;
	for (i = 0; i < listeImages.size(); i++)
	{
		if (checkedIndex[i])
		{
			imagesSelectionnes.append(listeImages[i]);
		}
	}

	Image im = *new Image();

	QList<QList<Image> > imagesClasses = im.classementImage(imagesSelectionnes);

	//affichage
	DialogAffichageCategories dial(this, imagesClasses);
	dial.exec();
}

void qt_bdm_remuaux_cartier::modifierInfos()
{
	bool ok;
	QString text = QInputDialog::getText(this, tr("Modification des infos"), tr("Nom"),
			QLineEdit::Normal, listeImages[ui.tabImages->currentIndex()].getNom().c_str(), &ok);
	if (ok && !text.isEmpty())
	{
		listeImages[ui.tabImages->currentIndex()].nom = text.toStdString();
		ui.tabImages->setTabText(ui.tabImages->currentIndex(), text);
	}
	text = QInputDialog::getText(this, tr("Modification des infos"), tr("Mot clef"),
			QLineEdit::Normal, listeImages[ui.tabImages->currentIndex()].motClef.c_str(), &ok);
	if (ok && !text.isEmpty())
	{
		listeImages[ui.tabImages->currentIndex()].motClef = text.toStdString();
	}
	text = QInputDialog::getText(this, tr("Modification des infos"), tr("Chemin"),
			QLineEdit::Normal, listeImages[ui.tabImages->currentIndex()].chemin.c_str(), &ok);
	if (ok && !text.isEmpty())
	{
		listeImages[ui.tabImages->currentIndex()].chemin = text.toStdString();
	}
}

void qt_bdm_remuaux_cartier::distLevenstein()
{
	int i, j;
	unsigned int result;
	QString affichage = "Distance de Levenstein entre chaqcun des mots clefs :\n";
	for (i = 0; i < listeImages.size(); i++)
	{
		if ((QString) listeImages.at(i).motClef.c_str() != "")
		{
			for (j = 0; j < i; j++)
			{
				if ((QString) listeImages.at(j).motClef.c_str() != "")
				{
					result = DistanceLevensthein(listeImages.at(i), listeImages.at(j));
					affichage += ((QString) ("   %1 - %2 : %3\n")).arg(
							listeImages.at(i).motClef.c_str()).arg(
							listeImages.at(j).motClef.c_str()).arg(result);
				}
			}
		}
	}
	QMessageBox::information(this, tr("Distance de Levenstein"), affichage);
}

void qt_bdm_remuaux_cartier::rechercheMotClef()
{
	int i;
	bool ok;
	QString affichage;
	QString text = QInputDialog::getText(this, tr("Recherche par mot clef"), tr("Mot clef:"),
			QLineEdit::Normal, tr(""), &ok);
	if (ok && !text.isEmpty())
	{
		affichage = "Résultats de la recherche :\n";

		for (i = 0; i < listeImages.size(); i++)
		{
			if ((QString) listeImages.at(i).motClef.c_str() != "" && (DistanceLevensthein(
					listeImages.at(i).motClef.c_str(), text.toStdString())) < 3)
			{
				affichage += ((QString) ("   %1 (mot clef : %2)\n")).arg(
						listeImages.at(i).getNom().c_str()).arg(listeImages.at(i).motClef.c_str());
			}
		}
	}
	QMessageBox::information(this, tr("Recherche par mot clef (%1)").arg(text), affichage);
}

void qt_bdm_remuaux_cartier::creationIndexChoixLot()
{
	DialogChoixLot dial(this, listeImages, DialogChoixLot::creationIndex);
	connect(&dial, SIGNAL(retourCreationIndex(bool*)), this, SLOT(creationIndex(bool *)));
	dial.exec();
}

void qt_bdm_remuaux_cartier::creationIndex(bool * checkedIndex)
{
	QList<Image> imagesSelectionnes = *new QList<Image> ();

	int i;
	for (i = 0; i < listeImages.size(); i++)
	{
		if (checkedIndex[i])
		{
			imagesSelectionnes.append(listeImages[i]);
		}
	}
	if (imagesSelectionnes.size() > 0)
	{
		arbreMotClef = creerBK_Tree(imagesSelectionnes, DistanceLevensthein);
		arbreHistograme = creerBK_Tree(imagesSelectionnes, distanceEuclidienneHistogrammes);
	}

	ui.actionRech_index_histo->setEnabled(true);
	ui.actionRech_Index_Mot_Clef->setEnabled(true);
}

void qt_bdm_remuaux_cartier::rechercheMotIndex()
{
	int i;
	bool ok, ok2;
	QString text = QInputDialog::getText(this, tr("Recherche indexee par mot clef"),
			tr("Mot clef:"), QLineEdit::Normal, tr(""), &ok);
	int marge = QInputDialog::getInt(this, tr("Recherche indexee par mot clef"), tr("Marge"), 0, 0,
			100, 1, &ok2, 0);
	QList<Image> result;
	if (ok && !text.isEmpty())
	{
		if (!ok2)
		{
			marge = 0;
		}
		Image img = Image();
		img.motClef = text.toStdString();
		result = arbreMotClef.rechercher(img, (unsigned int) marge);
	}

	QString affichage = "Résultats de la recherche :\n";

	for (i = 0; i < result.size(); i++)
	{
		affichage
				+= ((QString) ("   %1 (mot clef : %2)\n")).arg(result.at(i).getNom().c_str()).arg(
						result.at(i).motClef.c_str());
	}

	QMessageBox::information(this, tr("Recherche indexee par mot clef (%1)").arg(text), affichage);

}

void qt_bdm_remuaux_cartier::rechercheHistoIndex()
{
	int i;
	bool ok2;
	int marge = QInputDialog::getInt(this, tr("Recherche indexee par mot clef"), tr("Marge"), 0, 0,
			100, 1, &ok2, 0);
	QList<Image> result;

	if (!ok2)
	{
		marge = 0;
	}
	result = arbreMotClef.rechercher(listeImages[ui.tabImages->currentIndex()],
			(unsigned int) marge);

	QString affichage = "Résultats de la recherche :\n";

	for (i = 0; i < result.size(); i++)
	{
		affichage
				+= ((QString) ("   %1 (mot clef : %2)\n")).arg(result.at(i).getNom().c_str()).arg(
						result.at(i).motClef.c_str());
	}

	QMessageBox::information(this, tr("Recherche indexee par histograme"), affichage);

}

void qt_bdm_remuaux_cartier::choixImageVersLsd44()
{
	DialogChoix2emeImage dial(this, ui.tabImages->currentIndex(), listeImages,
			DialogChoix2emeImage::imageMemeTaille);
	connect(&dial, SIGNAL(retourDialogMemeTaille(int)), this, SLOT(versLsd44(int)));
	dial.exec();
}

void qt_bdm_remuaux_cartier::versLsd44(int indexePorteuse)
{
	Image img = toLsd44(listeImages[indexePorteuse], listeImages[ui.tabImages->currentIndex()]);
	ajoutImageATab(&img);

}

void qt_bdm_remuaux_cartier::deLsd44()
{
	Image porteuse = Image();
	Image cachee = Image();
	fromLsd44(listeImages[ui.tabImages->currentIndex()], &porteuse, &cachee);
	ajoutImageATab(&porteuse);
	ajoutImageATab(&cachee);
}

void qt_bdm_remuaux_cartier::choixImageVersLsd()
{
	DialogChoix2emeImage dial(this, ui.tabImages->currentIndex(), listeImages,
			DialogChoix2emeImage::imagePasMemeTaille);
	connect(&dial, SIGNAL(retourDialogPasMemeTaille(int)), this, SLOT(versLsd(int)));
	dial.exec();
}

void qt_bdm_remuaux_cartier::versLsd(int indexePorteuse)
{
	Image img = toLsd(listeImages[indexePorteuse], listeImages[ui.tabImages->currentIndex()]);
	ajoutImageATab(&img);

}

void qt_bdm_remuaux_cartier::deLsd()
{
	Image porteuse = Image();
	Image cachee = Image();
	fromLsd(listeImages[ui.tabImages->currentIndex()], &porteuse, &cachee);
	ajoutImageATab(&porteuse);
	ajoutImageATab(&cachee);
}
